#include "VQWK.hh"

const unsigned int VQWK::VQWK_SLOT_ID_MASK              = 0xf8000000;
const unsigned int VQWK::VQWK_WORD_TYPE_MASK            = 0x07000000;
const unsigned int VQWK::VQWK_CRATE_NUMBER_MASK         = 0x00ff0000;
const unsigned int VQWK::VQWK_HIT_CHANNELS_MASK         = 0x00003f00;
const unsigned int VQWK::VQWK_EVENT_COUNTER_MASK        = 0x00ffffff;
const unsigned int VQWK::VQWK_CHANNEL_NUMBER_MASK       = 0x001f0000;
const unsigned int VQWK::VQWK_DATA_VALID_MASK           = 0x00004000;
const unsigned int VQWK::VQWK_UNDER_THRESHOLD_MASK      = 0x00002000;
const unsigned int VQWK::VQWK_OVERFLOW_MASK             = 0x00001000;
const unsigned int VQWK::VQWK_DATA_MASK                 = 0x00000fff;

const unsigned int VQWK::VQWK_WORD_TYPE_NOT_VALID_DATUM = 6;
const unsigned int VQWK::VQWK_WORD_TYPE_HEADER          = 2;
const unsigned int VQWK::VQWK_WORD_TYPE_END_OF_BLOCK    = 4;
const unsigned int VQWK::VQWK_WORD_TYPE_VALID_DATUM     = 0;


VQWK::VQWK()
{ 

  slot_id                   = 0;
  word_type                 = 0;
  crate_number              = 0;
  hit_channels              = 0;
  event_counter             = 0;
  channel_number            = 0;

  data_valid                = 0;
  overflow                  = 0;
  underthreshold            = 0;

  data                      = 0;
  word_type_not_valid_datum = 0;
  word_type_header          = 0;
  word_type_end_of_block    = 0;
  word_type_valid_datum     = 0;
  word_type_reserved        = 0;
 
  return_decoded_data.clear();
  decoded_stream.clear();

};

VQWK::VQWK(const char *char_wrd)
{ 
  Decode( char_wrd );
  
};



VQWK::~VQWK() { };


void VQWK::Decode(const char *char_wrd)
{
  unsigned long int wrd =  strtoul (char_wrd, NULL, 16);
  
  if(wrd != 0) {
    slot_id   = BitMaskShift(wrd, VQWK_SLOT_ID_MASK,   27);
    word_type = BitMaskShift(wrd, VQWK_WORD_TYPE_MASK, 24);
    
    decoded_stream << "----------------------------------------- \n";
    decoded_stream << "       VQWK at Slot " << slot_id <<"\n";
    decoded_stream << "----------------------------------------- \n";
    decoded_stream << "  Input HEX number : " << char_wrd << "\n";
    decoded_stream << "  Word Type        : " << word_type    << "\n";
    
    if(word_type == VQWK_WORD_TYPE_VALID_DATUM) {
      data           = BitMaskShift(wrd, VQWK_DATA_MASK,             0);
      overflow       = BitMaskShift(wrd, VQWK_OVERFLOW_MASK,        12);
      underthreshold = BitMaskShift(wrd, VQWK_UNDER_THRESHOLD_MASK, 13);
      channel_number = BitMaskShift(wrd, VQWK_CHANNEL_NUMBER_MASK,  16);
      decoded_stream << "  Data Word  \n";
      decoded_stream << "  -- Overflow        : " << std::dec << overflow << "\n";
      decoded_stream << "  -- Under Threshold : " << underthreshold << "\n";
      decoded_stream << "  -- Channel Number  : " << channel_number << "\n";
      decoded_stream << "  -- Data            : " << data << "\n";
    }
    else if (word_type == VQWK_WORD_TYPE_HEADER ) {
      hit_channels   = BitMaskShift(wrd, VQWK_HIT_CHANNELS_MASK,  8);
      crate_number   = BitMaskShift(wrd, VQWK_CRATE_NUMBER_MASK, 16);
      
      decoded_stream << "  Header Word  \n";
      decoded_stream << "  -- Recorded Channel Number : " << hit_channels << "\n";
      decoded_stream << "  -- Crate   Number          : " << crate_number   << "\n";
    }
    else if (word_type == VQWK_WORD_TYPE_END_OF_BLOCK ) {
      event_counter = BitMaskShift(wrd, VQWK_EVENT_COUNTER_MASK, 0);
      decoded_stream << "  End Of Buffer Word  \n";
      decoded_stream << "  -- Event Counter : " << event_counter << "\n";
    }
    else if (word_type == VQWK_WORD_TYPE_NOT_VALID_DATUM ) {
      decoded_stream << "  This entry is NOT VALID DATUM \n";
    }
    else {
      decoded_stream << "  This entry is not defined in VQWK VME module \n";
      decoded_stream << "  this word of type is for reserved.\n";
    }
  }
  else {
    decoded_stream << "No HEX number is the input Entry" << std::endl;
    data_input_flag = false;
  }
  
  decoded_stream << std::endl;
  return_decoded_data = decoded_stream.str();
  
  return;
};

